package com.itheima.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.constant.MessageConstant;
import com.itheima.entity.Result;
import com.itheima.service.MemberService;
import com.itheima.service.OrderService;
import com.itheima.service.ReportService;
import com.itheima.service.SetmealService;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 统计
 */
@RestController
@RequestMapping("/report")
public class ReportController {

   @Reference
   private MemberService memberService;
   @Reference
   private SetmealService setmealService;
   @Reference
   private OrderService orderService;
   @Reference
   private ReportService reportService;

   /**
    * 会员数量统计
    * @return
    */
   @RequestMapping("/getMemberReport")
   public Result getMemberReport() {
      try {
         Map<String, Object> data = new HashMap<>();
         //添加月份数据
         List<String> months = new ArrayList<>();
         Calendar calendar = Calendar.getInstance();
         //获取前一年的今天
         calendar.add(Calendar.YEAR, -1);
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM");
         for (int i = 0; i < 12; i++) {
            //将日期转指定字符串后添加到months集合
            months.add(sdf.format(calendar.getTime()));
            //月份加一
            calendar.add(Calendar.MONTH,1);
         }
         data.put("months",months);

         //添加月份对应的会员数量
         List<Integer> memberCount = memberService.findCountByMonth(months);

         data.put("memberCount", memberCount);

         return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS, data);
      } catch (Exception e) {
         e.printStackTrace();
         return new Result(false, MessageConstant.GET_MEMBER_NUMBER_REPORT_FAIL);
      }
   }

   /**
    * 套餐到诊数统计
    * @return
    */
   @RequestMapping("/getSetmealReport")
   public Result getSetmealReport() {
      try {
         //创建返回数据对象
         Map<String, Object> data = new HashMap<>();

         //封装setmealCount数据
         List<Map<String, Object>> setmealCount = setmealService.getSetmealCount();
         data.put("setmealCount", setmealCount);

         //封装setmealNames数据
         List<String> setmealNames = new ArrayList<>();
         if (setmealCount != null && setmealCount.size() > 0) {
            //遍历setmealCount集合,从中取出套餐名字,封装到setmealNames中
            for (Map<String, Object> map : setmealCount) {
               setmealNames.add((String) map.get("name"));
            }
         }
         data.put("setmealNames", setmealNames);

         return new Result(true,MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS,data);
      } catch (Exception e) {
         e.printStackTrace();
         return new Result(false, MessageConstant.GET_SETMEAL_COUNT_REPORT_FAIL);
      }
   }

   /**
    * 运营数据统计
    * @return
    */
   @RequestMapping("/getBusinessReportData")
   public Result getBusinessReportData() {
      try {
         //调用服务,获取数据
         Map<String, Object> data = reportService.getBusinessReport();

         return new Result(true,MessageConstant.GET_BUSINESS_REPORT_SUCCESS,data);
      } catch (Exception e) {
         e.printStackTrace();
         return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
      }
   }

   /**
    * 导出运营统计表
    * @return
    */
   @RequestMapping("/exportBusinessReport")
   public Result exportBusinessReport(
      HttpServletRequest request,
      HttpServletResponse response) {

      try {
         //1.加载文件到poi对象中
         //1.1获取文件真实路径
         String realPath = request.getSession().getServletContext()
            .getRealPath("template") + File.separator + "report_template.xlsx";

         //1.2创建文件poi工作簿对象
         //XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(new File(realPath)));
         XSSFWorkbook workbook = new XSSFWorkbook(realPath);

         //2.获取数据
         Map<String, Object> map = reportService.getBusinessReport();
         String reportDate = (String) map.get("reportDate");
         Integer todayNewMember = (Integer) map.get("todayNewMember");
         Integer totalMember = (Integer) map.get("totalMember");
         Integer thisWeekNewMember = (Integer) map.get("thisWeekNewMember");
         Integer thisMonthNewMember = (Integer) map.get("thisMonthNewMember");
         Integer todayOrderNumber = (Integer) map.get("todayOrderNumber");
         Integer todayVisitsNumber = (Integer) map.get("todayVisitsNumber");
         Integer thisWeekOrderNumber = (Integer) map.get("thisWeekOrderNumber");
         Integer thisWeekVisitsNumber = (Integer) map.get("thisWeekVisitsNumber");
         Integer thisMonthOrderNumber = (Integer) map.get("thisMonthOrderNumber");
         Integer thisMonthVisitsNumber = (Integer) map.get("thisMonthVisitsNumber");
         List<Map<String,Object>> hotSetmeal = (List<Map<String, Object>>) map.get("hotSetmeal");

         //3.将数据写入到文件中
         //3.1获取页签
         XSSFSheet sheet = workbook.getSheetAt(0);
         //3.2在第3行第6个单元格写数据
         XSSFRow row = sheet.getRow(2);
         row.getCell(5).setCellValue(reportDate);//日期

         row = sheet.getRow(4);
         row.getCell(5).setCellValue(todayNewMember);//新增会员数
         row.getCell(7).setCellValue(totalMember);//总会员数

         row = sheet.getRow(5);
         row.getCell(5).setCellValue(thisWeekNewMember);//本周新增会员数
         row.getCell(7).setCellValue(thisMonthNewMember);//本月新增会员数

         row = sheet.getRow(7);
         row.getCell(5).setCellValue(todayOrderNumber);//今日预约数
         row.getCell(7).setCellValue(todayVisitsNumber);//今日到诊数

         row = sheet.getRow(8);
         row.getCell(5).setCellValue(thisWeekOrderNumber);//本周预约数
         row.getCell(7).setCellValue(thisWeekVisitsNumber);//本周到诊数

         row = sheet.getRow(9);
         row.getCell(5).setCellValue(thisMonthOrderNumber);//本月预约数
         row.getCell(7).setCellValue(thisMonthVisitsNumber);//本月到诊数
         
         //热门套餐
         int rowNum = 12;
         for (Map<String, Object> setmeal : hotSetmeal) {
            row = sheet.getRow(rowNum);
            row.getCell(4).setCellValue((String) setmeal.get("name"));//套餐名称
            row.getCell(5).setCellValue((Long)setmeal.get("setmeal_count"));//预约数量
            row.getCell(6).setCellValue(((BigDecimal) setmeal.get("proportion")).doubleValue());//占比
            rowNum ++;
         }

         //4.通过网络流将文件写出
         ServletOutputStream outputStream = response.getOutputStream();
         response.setContentType("application/vnd.ms-excel");
         response.setHeader("content-Disposition","attachment;filename=report.xlsx");

         workbook.write(outputStream);
         outputStream.flush();
         outputStream.close();
         workbook.close();
         return null;
      } catch (Exception e) {
         e.printStackTrace();
         return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
      }

   }

   /**
    * 导出运营数据PDF文件
    * @return
    */
   @RequestMapping("/exportBusinessReport4PDF")
   public Result exportBusinessReport4PDF(
      HttpServletRequest request,HttpServletResponse response) {
      try {
         //1.定义模板文件和编译后文件的绝对路径
         String jrxmlPath = request.getSession().getServletContext().getRealPath("template") + File.separator + "health_business3.jrxml";
         String jasperPath = request.getSession().getServletContext().getRealPath("template") + File.separator + "health_business3.jasper";
         //2.编译模板文件
         JasperCompileManager.compileReportToFile(jrxmlPath,jasperPath);
         //3.准备数据
         Map<String, Object> map = reportService.getBusinessReport();
         List<Map> hotSetmeal = (List<Map>) map.get("hotSetmeal");
         //4.填充数据
         JasperPrint jasperPrint = JasperFillManager.fillReport(jasperPath, map, new JRBeanCollectionDataSource(hotSetmeal));
         //5.导出PDF文件
         ServletOutputStream out = response.getOutputStream();
         response.setContentType("application/pdf");
         response.setHeader("Content-Disposition","attachment;filename*=utf-8'zh_cn'"+ URLEncoder.encode("运营统计表.pdf","utf-8"));
         //response.setHeader("Content-Disposition","attachment;filename=运营统计表.pdf");
         JasperExportManager.exportReportToPdfStream(jasperPrint,out);
         return null;
      } catch (Exception e) {
         e.printStackTrace();
         return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
      }
   }

}
